# -*- coding: utf-8 -*-

from __future__ import division
import os
import sys
sys.path.append('../')
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import Normalizer
from sklearn.svm import SVC
from sklearn.externals import joblib
from model.default import svm_model



def train( data:pd.DataFrame, Xlst:list, Ylst:list, 
            C=1.0, coef0=0.0, kernel='linear', gamma='auto', random_state=None, tol=1e-6, 
            probability=True, cache_size=1024, **kw):
    assert isinstance(data, pd.DataFrame), '"data" must be given as a pd.DataFrame obj'
    assert isinstance(Xlst, list), '"Xlst" must be given as a list obj'
    assert isinstance(Ylst, list), '"Ylst" must be given as a list obj'

    svm = SVC( C=C, 
            coef0=coef0,
            kernel=kernel, 
            gamma=gamma, 
            random_state=random_state,
            tol=tol,
            probability=probability,
            cache_size=cache_size,
            **kw
        )
        
    model = Pipeline([
        ('norm', Normalizer(norm='l1')),
        ('svc', svm)
    ])

    X_data = data[Xlst].values
    Y_label = data[Ylst].values.flatten()
    
    model.fit(X_data, Y_label)
    with open(svm_model, mode='wb+') as fp:
        joblib.dump(model, fp)
    print('训练完毕, SVM模型保存在 %s' % svm_model)


def test(test:pd.DataFrame, Xlst:list, Ylst:list):
    """测试模型准确率
    
    Arguments:
        test {pd.DataFrame} -- 测试数据集
        Xlst {list} -- 指定数据列
        Ylst {list} -- 标签数据列
    """

    with open(svm_model, mode='rb') as fp:
        svm = joblib.load(fp)
    data = test[Xlst].values
    Y_label = test[Ylst].values.flatten()
    p_label = svm.predict(data)
    rsl = p_label == Y_label
    print('Test accuracy --> {}'.format(sum(rsl)/len(rsl)))    


def predict(user: pd.DataFrame):
    """SVM预测函数
    
    Arguments:
        user {pd.DataFrame} -- 用户数据
        uid {str} -- 用户id
    """

    with open(svm_model, mode='rb') as fp:
        svm = joblib.load(fp)
    rsl = svm.predict(user.values.reshape(1, -1))
    return rsl

